package com.jmp.api.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.vioao.wechat.api.component.ComponentApi;
import com.github.vioao.wechat.api.component.wxa.TemplateApi;
import com.github.vioao.wechat.bean.response.component.GetAuthorizerInfoResponse;
import com.github.vioao.wechat.bean.response.component.GetAuthorizerTokenResponse;
import com.github.vioao.wechat.bean.response.component.GetComponentTokenResponse;
import com.github.vioao.wechat.bean.response.component.wxa.template.LibraryAddResponse;
import com.github.vioao.wechat.bean.response.component.wxa.template.LibraryListResponse;
import com.github.vioao.wechat.bean.response.component.wxa.template.TemplateListResponse;
import com.jmp.api.service.WechatComponentService;
import com.jmp.base.dto.MessageWxNoticeEnums;
import lombok.extern.slf4j.Slf4j;
import one.stand.code.RedisCode;
import one.stand.config.ComponentConfig;
import one.stand.enums.LoginEnum;
import one.stand.mapper.WxNoticeMapper;
import one.stand.model.WxNoticeModel;
import one.stand.util.DateUtil;
import one.stand.util.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author cjr
 */
@Service
@Slf4j
public class WechatComponentServiceImpl implements WechatComponentService {
    private ComponentApi componentApi = new ComponentApi();

    @Autowired
    private ComponentConfig componentConfig;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private WxNoticeMapper wxNoticeMapper;

    @Override
    public String getComponentToken() {
        String ticket = redisUtil.get(RedisCode.getTicket(componentConfig.getAppid()));
        String key = RedisCode.getComponentTokenKey(componentConfig.getAppid());
        String token = redisUtil.get(key);
        if (null == token) {
            GetComponentTokenResponse getComponentTokenResponse = componentApi.getComponentToken(componentConfig.getAppid(), componentConfig.getSecret(), ticket);
            if (getComponentTokenResponse.isSuccess()) {
                token = getComponentTokenResponse.getComponentAccessToken();
                redisUtil.set(key, token, 100, TimeUnit.MINUTES);
            }
            log.info("componentToken:{}", JSON.toJSONString(getComponentTokenResponse));
        }
        return token;
    }

    @Override
    public String getAuthorizerToken(String appid) {
        String key = RedisCode.getAuthorizerToken(appid);
        String token = redisUtil.get(key);
        if (StringUtils.isEmpty(token)) {
            String componentToken = getComponentToken();
            String authorizerRefreshToken = getAuthorizerRefreshToken(appid);
            GetAuthorizerTokenResponse getAuthorizerTokenResponse = componentApi.getAuthorizerToken(componentToken, componentConfig.getAppid(), appid, authorizerRefreshToken);
            if (getAuthorizerTokenResponse.isSuccess()) {
                token = getAuthorizerTokenResponse.getAuthorizerAccessToken();
                redisUtil.set(key, token, 100, TimeUnit.MINUTES);
            }
        }
        return token;
    }

    @Override
    @Async("asyncServiceExecutor")
    public void templateInit(Integer companyId, LoginEnum loginEnum, String appId) {
        log.info("小程序微信模板添加：{} {} {}", companyId, loginEnum, appId);
        MessageWxNoticeEnums[] wxNoticeEnums = MessageWxNoticeEnums.values();
        String loginType = loginEnum.getCode().toUpperCase();
        for (MessageWxNoticeEnums enums : wxNoticeEnums) {
            if (org.apache.commons.lang3.StringUtils.isBlank(enums.getNoticeId())) continue;
            if (enums.getType().equals(loginType) && org.apache.commons.lang3.StringUtils.isNoneBlank(enums.getNoticeId())) {
                log.info("WxController#addTemplate appId={} name={}", appId, enums.getName());
                LibraryAddResponse libraryAddResponse = libraryAdd(appId, enums.getNoticeId(), enums.getData());
                WxNoticeModel wxNoticeModel = new WxNoticeModel();
                wxNoticeModel.setCompanyId(companyId);
                wxNoticeModel.setWxNoticeName(enums.getName());
                wxNoticeModel.setCode(enums.getCode());
                wxNoticeModel.setValue(libraryAddResponse.getTemplateId());
                wxNoticeModel.setType(enums.getType());
                wxNoticeModel.setPage(enums.getPage());
                wxNoticeModel.setCreateTime(DateUtil.currentDate());
                wxNoticeMapper.insertSelective(wxNoticeModel);
            }
        }
    }

    private LibraryListResponse libraryList(String appId, Integer offset, Integer count) {
        String tokne = getAuthorizerToken(appId);
        LibraryListResponse response = TemplateApi.libraryList(tokne, offset, count);
        log.info("模板列表：{}", JSON.toJSONString(response));
        return response;
    }

    private LibraryAddResponse libraryAdd(String appId, String noticeId, Integer... code) {
        String token = getAuthorizerToken(appId);
        List<Integer> keywordIdList = new ArrayList<>();
        for (Integer id : code) {
            keywordIdList.add(id);
        }
        LibraryAddResponse response = TemplateApi.libraryAdd(token, noticeId, JSON.toJSONString(keywordIdList));
        return response;
    }

    private TemplateListResponse list(String appId, Integer offset, Integer count) {
        String token = getAuthorizerToken(appId);
        TemplateListResponse response = TemplateApi.list(token, offset, count);
        return response;
    }

    private String getAuthorizerRefreshToken(String appid) {
        String key = RedisCode.getAuthorizerRefreshTokenKey(appid);
        String token = redisUtil.get(key);
        if (StringUtils.isEmpty(token)) {
            GetAuthorizerInfoResponse response = componentApi.getAuthorizerInfo(getComponentToken(), componentConfig.getAppid(), appid);
            log.info("获取代小程序账号信息：{}", JSON.toJSONString(response));
            if (response.isSuccess()) {
                token = response.getAuthorizationInfo().getAuthorizerAccessToken();
                if (StringUtils.isEmpty(token)) {
                    token = response.getAuthorizationInfo().getAuthorizerRefreshToken();
                }
                redisUtil.set(key, token, 10, TimeUnit.MINUTES);

            }
        }
        return token;
    }
}
